package battleship.data;

import java.io.File;
import java.util.Comparator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Scores {


	private String name;
	private int wins;
	private int losses;
	
	private Document doc;
	private File file;

	public Scores (String name, int wins, int losses)
	{
		this.name = name;
		this.wins = wins;
		this.losses = losses;
	}

	public String getName()
	{
		return name;
	}

	public float getRatio()
	{
		if (losses == 0)
		{
			return 0;
		}
		return (float) wins / (float) losses;
	}

	public int getWins()
	{
		return wins;
	}

	public int getLosses()
	{
		return losses;
	}

	public void increaseWins()
	{
		wins++;
	}

	public void increaseLosses()
	{
		losses++;
	}

	public enum SortParameters
	{
		NAME,
		AVERAGE,
		TURNS,
		WINS,
		LOSSES,
		RATIO,
	}

	public static Comparator<Scores> getComparator(SortParameters... sortParameters)
	{
		return new ScoresComparator(sortParameters);
	}

	public static class ScoresComparator implements Comparator<Scores>
	{
		private SortParameters[] parameters;

		private ScoresComparator(SortParameters[] parameters) {
			this.parameters = parameters;
		}

		public int compare(Scores o1, Scores o2) {
			int comparison;
			float floatingComparison;

			for(SortParameters parameter : parameters)
			{
				switch (parameter)
				{
				case WINS:
					comparison = o2.getWins() - o1.getWins();
					if(comparison != 0) return comparison;
				case LOSSES:
					comparison = o1.getLosses() - o2.getLosses();
					if(comparison != 0) return comparison;
				case NAME:
					comparison = o1.getName().compareToIgnoreCase(o2.getName());
					if (comparison != 0) return comparison;
				case RATIO:
					floatingComparison = o1.getRatio() - o2.getRatio();
					if (floatingComparison != 0)
					{
						if(floatingComparison > 0)
						{
							floatingComparison+=0.5;
							return (int) floatingComparison;
						}
						else
						{
							floatingComparison-=0.5;
							return (int) floatingComparison;
						}
					}
					break;
				}
			}
			return 0;
		}



	}
	
	public void toSave()
	{
		File scores = new File("scores");
		if(!scores.exists())
		{
			scores.mkdir();
		}
		
		try
		{
			file = new File("scores/" + getName() + ".xml");

			if(file.exists())
			{
				file.delete();
				file.createNewFile();
			}


			createDOMtree();
			transform();
		}
		catch (Exception e)
		{
			System.err.println("De speler " + getName() + " kon niet opgeslagen worden");
		}
	}
	
	public void createDOMtree() throws ParserConfigurationException
	{
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();

		doc = db.newDocument();
		
		Element root = doc.createElement("scores");
		doc.appendChild(root);
		
		Element name = doc.createElement("name");
		name.setTextContent(getName());
		root.appendChild(name);
		
		Element wins = doc.createElement("wins");
		wins.setTextContent(String.valueOf(getWins()));
		root.appendChild(wins);
		
		Element losses = doc.createElement("losses");
		losses.setTextContent(String.valueOf(getLosses()));
		root.appendChild(losses);
	}
	
	
	public void transform() throws TransformerException
	{
		TransformerFactory tff = TransformerFactory.newInstance();
		tff.setAttribute("indent-number", 4);
		
		Transformer trans = tff.newTransformer();
		
		trans.setOutputProperty(OutputKeys.INDENT, "true");
		DOMSource src = new DOMSource(doc);
		
		StreamResult result = new StreamResult(file);
		
		trans.transform(src, result);
	}
}
